﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using ProgNetComponentsDx.Forms;

namespace Wydatki.WRK.Lotto
{
    public partial class FormWrkLottoLosowania : MyBaseSqlCeGridForm
    {
        DataSets.LottoLosowaniaDataSet copyDs = new DataSets.LottoLosowaniaDataSet();
        private object lockDs = new object();
        private int max;
        FormBackgroundWorkMultiThread multiThreadForm = null;
        public FormWrkLottoLosowania()
        {
            InitializeComponent();
            bar1.SetItemPosition(bsiLayout, bar1.LinksPersistInfo.Count-1);
            ChangeOrder();
        }
        private void ChangeOrder()
        {
            gvMain.RowCellStyle -= new DevExpress.XtraGrid.Views.Grid.RowCellStyleEventHandler(gvMain_RowCellStyle);
            gvMain.RowCellStyle+=new DevExpress.XtraGrid.Views.Grid.RowCellStyleEventHandler(gvMain_RowCellStyle);
        }
        private void bbiDodajLosowania_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            FormNoweLosowania f = new FormNoweLosowania();
            if (f.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                string[] lines = f.Lines;
                string mask = "";
                string data = "";
                string day, month, year;
                string dateMask =@"^(\d+)[^0-9]+(\d+)[^0-9]+(\d+)$";
                List<int> liczby = new List<int>();
                DataRow newLosowanie;
                try
                {
                    foreach (string s in lines)
                    {
                        mask = @"(\d*[^0-9]+)?(\d+[^0-9]+\d+[^0-9]+\d+)[^0-9]+(\d+)[^0-9]+(\d+)[^0-9]+(\d+)[^0-9]+(\d+)[^0-9]+(\d+)[^0-9]+(\d+)";
                        if (s.XMatch(mask))
                        {
                            data = s.GetFirstMatch(mask, 2);
                            day = month = year = "";
                            switch (f.DateFormat)
                            {
                                case "dd/mm/RRRR":
                                    day = data.GetFirstMatch(dateMask, 1);
                                    month = data.GetFirstMatch(dateMask, 2);
                                    year = data.GetFirstMatch(dateMask, 3);
                                    break;
                                case "mm/dd/RRRR":
                                    day = data.GetFirstMatch(dateMask, 2);
                                    month = data.GetFirstMatch(dateMask, 1);
                                    year = data.GetFirstMatch(dateMask, 3);
                                    break;
                                case "RRRR/mm/dd":
                                    day = data.GetFirstMatch(dateMask, 3);
                                    month = data.GetFirstMatch(dateMask, 2);
                                    year = data.GetFirstMatch(dateMask, 1);
                                    break;
                                case "RRRR/dd/mm":
                                    day = data.GetFirstMatch(dateMask, 2);
                                    month = data.GetFirstMatch(dateMask, 3);
                                    year = data.GetFirstMatch(dateMask, 1);
                                    break;
                            }
                            DateTime d = DateTime.MinValue;

                            if (day.IsNotNull() && month.IsNotNull() && year.IsNotNull())
                            {
                                d = new DateTime(year.AsInt(), month.AsInt(), day.AsInt());

                                newLosowanie = lottoLosowaniaDataSet1.WRK_LOTTO_LOSOWANIA.NewRow();
                                newLosowanie["WRK_LL_DATA"] = d;
                                lottoLosowaniaDataSet1.WRK_LOTTO_LOSOWANIA.AddWRK_LOTTO_LOSOWANIARow(d,
                                    s.GetFirstMatch(mask, 3).AsInt(),
                                    s.GetFirstMatch(mask, 4).AsInt(),
                                    s.GetFirstMatch(mask, 5).AsInt(),
                                    s.GetFirstMatch(mask, 6).AsInt(),
                                    s.GetFirstMatch(mask, 7).AsInt(),
                                    s.GetFirstMatch(mask, 8).AsInt());
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    ex.Log();
                    this.ShowDxErrorDialog("Błąd dodawania losowania. Losowanie powinno być w formacie: Data liczby");
                }
            }
            f.Dispose();
        }

        private void bbiSzukajLosowan_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            if (!Tools.WebTools.CheckConnection())
            {
                this.ShowDxErrorDialog("Nie można połączyć z internetem.");
                return;
            }
            max = 0;

            FormSzukanieLosowan f = new FormSzukanieLosowan();
            if (f.ShowDialog() != System.Windows.Forms.DialogResult.OK)
                return;
            int odRoku = Math.Max(1957, f.OdRoku);
            int doRoku = Math.Min(f.DoRoku, DateTime.Now.Year);
            multiThreadForm = new FormBackgroundWorkMultiThread();
            multiThreadForm.BackgroundControl.ProgressType = ProgressType.Percentage;

            if (doRoku > 0)
            {
                int rok = odRoku;
                List<int> lista = new List<int>();
                while (rok < doRoku)
                {
                    lista.Add(rok);
                    rok++;
                }
                lista.Add(rok);
                int i=0;
                int maxLata = lista.Count / 10;
                if (lista.Count % 10 != 0)
                    maxLata += 1;

                List<int> lata = new List<int>();
                while (i < lista.Count)
                {
                    if (lata.Count == maxLata)
                    {
                        max += maxLata * 12;
                        multiThreadForm.AddAction(new Action<int[], WebClient>(PobierzDaneRoczne), new object[] { lata.ToArray(), Tools.WebTools.CreateWebClient() });
                        lata.Clear();
                    }
                    lata.Add(lista[i]);
                    i++;
                }
                if (lata.Count > 0)
                {
                    multiThreadForm.AddAction(new Action<int[], WebClient>(PobierzDaneRoczne), new object[] { lata.ToArray(), Tools.WebTools.CreateWebClient() });
                    max += lata.Count * 12;
                }
            }
            else
            {
                int odM = Math.Max(1, f.OdMiesiaca);
                int doM = f.DoMiesiaca;
                if (doM < 1)
                    doM = 12;
                for (int i=odM; i <= doM; i++)
                {
                    multiThreadForm.AddAction(new Action<int, int, WebClient>(PobierzDaneMiesieczne), new object[] { odRoku, i, Tools.WebTools.CreateWebClient() });
                    max++;
                }
            }
            multiThreadForm.BackgroundControl.LabelText = ("Liczba miesięcy do sprawdzenia: " + max);
            multiThreadForm.BackgroundControl.MaxProgress = max;
            progressReporter1.Form = multiThreadForm;
            progressReporter1.Start();
            DialogResult dlg = multiThreadForm.ShowDialog();
            progressReporter1.Stop();
            switch (dlg)
            {
                case System.Windows.Forms.DialogResult.Cancel:
                    this.ShowDxInfoDialog("Przerwa na rzyczenie użytkownika");
                    break;
                case System.Windows.Forms.DialogResult.Abort:
                    this.ShowDxErrorDialog("Błąd!");
                    break;
                case System.Windows.Forms.DialogResult.OK:
                    multiThreadForm = new FormBackgroundWorkMultiThread();
                    multiThreadForm.BackgroundControl.SupportCancelation = false;
                    multiThreadForm.AddAction(new Action(KasujNiepotrzebne), null);
                    multiThreadForm.BackgroundControl.LabelText = ("Kasowanie podwojonych wpisów");
                    max = copyDs.WRK_LOTTO_LOSOWANIA.Rows.Count;
                    multiThreadForm.BackgroundControl.MaxProgress = max;

                    progressReporter1.Form = multiThreadForm;
                    progressReporter1.Start();
                    multiThreadForm.ShowDialog();
                    progressReporter1.Stop();
                    foreach (DataRow r in copyDs.WRK_LOTTO_LOSOWANIA.Rows)
                    {
                        if (r.CanRead())
                            lottoLosowaniaDataSet1.WRK_LOTTO_LOSOWANIA.ImportRow(r);
                    }
                    break;
            }
        }
        private void KasujNiepotrzebne()
        {
            DataRow[] rows = copyDs.WRK_LOTTO_LOSOWANIA.Select();
            int i=0;
            foreach (DataRow r in rows)
            {
                multiThreadForm.BackgroundControl.Progress = i++;
                if (RowExists(r))
                {
                    r.Delete();
                }
            }
        }
        private bool RowExists(DataRow r)
        {
            string select = "";
            for(int i=1;i<7;i++)
            {
                select = select.AppendAnd();
                select+=" WRK_LL_LICZBA"+i+" = " + r["WRK_LL_LICZBA"+i].AsString();
            }
            DataRow[] rows = lottoLosowaniaDataSet1.WRK_LOTTO_LOSOWANIA.Select(select);
            if (rows.Length > 0)
            {
                DateTime d1 = r["WRK_LL_DATA"].AsDateTime(DateTime.MinValue);
                DateTime d2;
                foreach (DataRow rr in rows)
                {
                    d2 = rr["WRK_LL_DATA"].AsDateTime(DateTime.MinValue);
                    if (d2.Year == d1.Year &&
                        d2.Month == d1.Month &&
                        d2.Day == d1.Day)
                        return true;
                }
            }
            return false;
        }

        private void PobierzDaneRoczne(int[] lata, WebClient client)
        {
            foreach (int rok in lata)
            {
                for (int miesiac=1; miesiac <= 12; miesiac++)
                {
                    if (multiThreadForm.BackgroundControl.IsCanceling)
                        return;
                    PobierzDaneMiesieczne(rok, miesiac, client);
                }
            }
        }

        private void PobierzDaneMiesieczne(int rok, int miesiac, WebClient client)
        {
            DataSets.LottoLosowaniaDataSet ds = new DataSets.LottoLosowaniaDataSet();
            progressReporter1.Progress++;
            string adres = "http:" + "//www.wyniki-lotto.pl/" + (miesiac < 10 ? "0" : "") + miesiac + "." + rok + ".html";

            string mask = @"\s*<td>\s*<a href=" + "\"" + @"/(\d+\.\d+\.\d+)\.html" + "\"" + @"><b>.*\1</b></a></td><td>\s*(\d+)</td><td>\s*(\d+)</td><td>\s*(\d+)</td><td>\s*(\d+)</td><td>\s*(\d+)</td><td>\s*(\d+)</td>";
            string dateMask =@"^(\d+)[^0-9]+(\d+)[^0-9]+(\d+)$";
            string page = client.DownloadString(adres);
            if (multiThreadForm.BackgroundControl.IsCanceling)
                return;
           
            List<Dictionary<int, string>> dic = page.GetMatches(mask, new int[] { 1, 2, 3, 4, 5, 6, 7 }, System.Text.RegularExpressions.RegexOptions.IgnoreCase | System.Text.RegularExpressions.RegexOptions.Multiline);
            string data;
            int day, month, year;
            foreach (Dictionary<int,string> zestaw in dic)
            {
                if (multiThreadForm.BackgroundControl.IsCanceling)
                    return;
                data = zestaw[1];
                day = data.GetFirstMatch(dateMask, 1).AsInt(-1);
                month = data.GetFirstMatch(dateMask, 2).AsInt(-1);
                year = data.GetFirstMatch(dateMask, 3).AsInt(-1);
                if (day > 0 && month > 0 && year > 0)
                {
                    ds.WRK_LOTTO_LOSOWANIA.AddWRK_LOTTO_LOSOWANIARow(
                        new DateTime(year, month, day),
                        zestaw[2].AsInt(),
                        zestaw[3].AsInt(),
                        zestaw[4].AsInt(),
                        zestaw[5].AsInt(),
                        zestaw[6].AsInt(),
                        zestaw[7].AsInt());
                }
            }
            lock (lockDs)
            {
                foreach (DataRow r in ds.WRK_LOTTO_LOSOWANIA.Rows)
                {
                    copyDs.WRK_LOTTO_LOSOWANIA.ImportRow(r);
                }
            }
        }
        
        protected override bool Save()
        {
            bool result = base.Save();
            if (result)
            {
                Tools.Lotto.LottoLosowaniaTools.SetLosowania(this.lottoLosowaniaDataSet1);
            }
            return result;
        }

        private void gvMain_RowCellStyle(object sender, DevExpress.XtraGrid.Views.Grid.RowCellStyleEventArgs e)
        {
            if (e.Column.FieldName.StartsWith("WRK_LL_LICZBA"))
            {
                if (tePokaz.EditValue.IsNotNull())
                {
                    string colval = gvMain.GetRowCellValue(e.RowHandle, e.Column).AsString();
                    if (colval.IsNotNull())
                    {
                        string[] str  = tePokaz.EditValue.AsString().Split(',');
                        if (str.Contains(colval))
                        {
                            e.Appearance.BackColor = Color.Red;
                        }
                    }
                }
            }
        }

        private void teFiltruj_EditValueChanged(object sender, EventArgs e)
        {
            string liczby =  teFiltruj.EditValue.AsString().TrimEnd(',');
            string filter = "";
            if (liczby.IsNotNull())
            {
                for (int i=1; i < 7; i++)
                {
                    filter = filter.AppendOr();
                    filter += "WRK_LL_LICZBA" + i + " IN (" + liczby + ")";
                }
            }
            gvMain.ActiveFilterString = filter;
        }

        private void tePokaz_EditValueChanged(object sender, EventArgs e)
        {
            gcMain.RefreshDataSource();
        }

        private void gvMain_KeyDown(object sender, KeyEventArgs e)
        {
            DataRow r = gvMain.GetFocusedDataRow();
            if (r == null)
                return;

            if (e.KeyCode == Keys.C && e.Control)
            {
                if (r != null)
                {
                    e.Handled = true;
                    string str = "";
                    for (int i=1; i < 7; i++)
                    {
                        str = str.AppendString(",");
                        str += r["WRK_LL_LICZBA" + i].AsString();
                    }
                    Clipboard.SetText(str);
                }
            }
            else if (e.KeyCode == Keys.F && e.Control)
            {
                if (r != null)
                {
                    e.Handled = true;
                    string str = "";
                    for (int i=1; i < 7; i++)
                    {
                        str = str.AppendString(",");
                        str += r["WRK_LL_LICZBA" + i].AsString();
                    }
                    teFiltruj.EditValue = str;
                }
            }
            else if (e.KeyCode == Keys.P && e.Control)
            {
                if (r != null)
                {
                    e.Handled = true;
                    string str = "";
                    for (int i=1; i < 7; i++)
                    {
                        str = str.AppendString(",");
                        str += r["WRK_LL_LICZBA" + i].AsString();
                    }
                    tePokaz.EditValue = str;
                }
            }

        }
    }
}
